/******************************************************************************
*  COPYRIGHT MorningCore CO.,LTD
******************************************************************************/

/*****************************************************************
* FileName::    <ue_tx_pusch_precoding_fix.c>
* version::     <1.0.0>
* Purpose:      <do pusch precoding, i.e hybrid radix dft>
* Authors:      <shanshan, 2022-11-25>
* Notes:        <no>
******************************************************************/

/******************************************************************************
*  HISTORY OF CHANGES
*   <Date>          <Author>        <Version>       <DESCRIPTION>
*   ...             ...              ...            ....
******************************************************************************/

/******************************************************************************
*  INCLUDE FILES

******************************************************************************/
#include "stdlib.h"
#include "../head/ue_tx_pusch_precoding_fix.h"
#include "../head/ue_tx_srp_pusch_fe_fix.h"
#include "../head/Ue_Tx_FilePrintf.h"
#include "../../../../CommLib_FltC/GlobalVarDef.h"
/*----------- function definition-----------------------------------*/
/*****************************************************************************
* Function: PUSCH_Precoding()
* Purpose:  This function performs precoding processing
*
* Relation:
Calls       : ....
Called by   : ....
* Params:
*   <Name>          <Type>      <In/Out>    <Description>
 LayerNum           int8          In        number of Layers
 PUSCH_TxPortNum    int8          In        number of TxPorts
 CodebookIndex      int8          In        index of codebook
 PUSCH_RB_Num       int8          In        RB number of PUSCH
 PUSCH_SymNum       int8          In        number of SC-FDMA symbols for PUSCH
 DMRSOp[4][2][1320]     cmplx_frN     In/Out    output of DMRS
* Return:  void
* Note:    
*******************************************************************************/
void PUSCH_Precoding_fix
(
    stULParamTable *SimParam,
    fractM BetaDMRS,
    OUT cmplx_frN *DMRSOp[RS_NUM_PER_TTI_UL]
)
{
    /*variables definition*/
	int DMRSReNum_PerSymb=0,DMRSReNum_PerSymb_Max = 275*12;// ReNum per symbol 
    int k,l,m,rs_pos,portIdx,isym_idx,count_sc;
    cmplx_frN *DataOp1[MAXSYMNUM]; 
	cmplx_frN RS_temp[RS_NUM_PER_TTI_UL][PUSCH_Max_RE];
	for (l = 0; l < MAXSYMNUM; l++)
	{
		DataOp1[l] = (cmplx_frN *)malloc((PUSCH_Max_RE) * sizeof(cmplx_frN));
		memset(DataOp1[l], 0, (PUSCH_Max_RE) * sizeof(cmplx_frN));
	}
    memset(RS_temp,0,sizeof(cmplx_frN)*PUSCH_Max_RE*RS_NUM_PER_TTI_UL);

	uint8 data_ind_map[MAXSYMNUM]={0};

    DMRSReNum_PerSymb = 6 * SimParam->PUSCH_RB_Num; //
    rs_pos =  SimParam->PUSCH_VRB_START * 6; //

    for (l = 0; l < SimParam->DMRS_NumInOneSlot; l++)
    {
        memcpy(&(RS_temp[l][rs_pos]), DMRSOp[l], sizeof(cmplx_frN)*DMRSReNum_PerSymb);
    }

	for(l=0; l<SimParam->DMRS_NumInOneSlot; l++)
	{
		for(k=0; k<DMRSReNum_PerSymb_Max;k++)
		{
			RS_temp[l][k].re = ((RS_temp[l][k].re*(int64)BetaDMRS))>>26;
			RS_temp[l][k].im = ((RS_temp[l][k].im*(int64)BetaDMRS))>>26;
		}
	}	
    vFilePrintbeta_seqPrint(SimParam,RS_temp);

	for (l=0; l<SimParam->DMRS_NumInOneSlot; l++)
    {
        for(k=0; k<DMRSReNum_PerSymb_Max; k=k+2)
        {	  
			DMRSOp[l][k].re = RS_temp[l][k].re;
			DMRSOp[l][k].im = RS_temp[l][k].im;
			DMRSOp[l][k+1].re = g_afWfNorm_fix[0][1]*RS_temp[l][k+1].re;
			DMRSOp[l][k+1].im = g_afWfNorm_fix[0][1]*RS_temp[l][k+1].im;					
		}
	}

	portIdx = 0;
	for( l=0; l<SimParam->DMRS_NumInOneSlot; l++ )
    {  
		isym_idx = SimParam->DMRS_SymIdx[l];				 
		count_sc =0;
		for(m=0;m<(DMRSReNum_PerSymb_Max/12);m++)
		{
			for(k=0; k<SC_PER_RB; k++ ) //275*12
			{		
				if(SimParam->pusch_re_flag_dmrsport[isym_idx][0][k] == portIdx)
				{
					DataOp1[l][m*SC_PER_RB+k]= DMRSOp[l][count_sc];
					count_sc = count_sc+1;
				}
				else
				{
					DataOp1[l][m*SC_PER_RB+k].re = 0;
					DataOp1[l][m*SC_PER_RB+k].im = 0;
				}
			}
		}
    }

	for( l=0; l<SimParam->DMRS_NumInOneSlot; l++ )
    {
		memcpy(DMRSOp[l],DataOp1[l],sizeof(cmplx_frN)*PUSCH_Max_RE);  //store original RS sequence
	}

	for (l = 0; l < MAXSYMNUM; l++)
	{
		free(DataOp1[l]);
	}
}